perm filename A17.TEX[106,RWF] blob
sn#807734 filedate 1985-11-04 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00002 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 \magnification\magstephalf
C00023 ENDMK
C⊗;
\magnification\magstephalf
\input macro.tex
\def\today{\ifcase\month\or
January\or February\or March\or April\or May\or June\or
July\or August\or September\or October\or November\or December\fi
\space\number\day, \number\year}
\baselineskip 14pt
\rm
\line{\sevenrm a17.tex[106,phy] \today\hfill}
\bigskip
\line{\bf Number Types\hfill}
\bigskip
In Pascal, every numerical
expression is implicitly marked with one of two symbols,
which have no visible representation, but which have far-reaching effects.
Since they are associated with the variable types {\tt REAL} and
{\tt INTEGER}, we will use {\bf r} and~{\bf i} to make them visible.
Numerical expressions labeled {\bf r} or~{\bf i}
are called real or integer expressions respectively.
\smallskip
\disleft 25pt:(1):
A numerical constant written without decimal point or exponent is marked
with~{\bf i}:
\smallskip
{\obeylines\obeyspaces\let =\ \tt
0$↓{\bf{i}}$,123$↓{\bf{i}}$,-4567890$↓{\bf{i}}$;
}
\smallskip
\disleft 25pt::
a constant written with decimal point and/or exponent is marked with {\bf r}:
\smallskip
{\obeylines\obeyspaces\let =\ \tt
0.0$↓{\bf{r}}$,12300E-2$↓{\bf{r}}$,-4.567890E6$↓{\bf{r}}$.
}
\smallskip
\disleft 25pt:(2):
Variables declared {\tt INTEGER} and {\tt REAL} are marked with {\bf i} and~{\bf r}
respectively.
\smallskip
{\obeylines\obeyspaces\let =\ \tt
VAR M,N: INTEGER; X,Y: REAL;
$\vdots$
WRITE(N$↓{\bf{i}}$,X$↓{\bf{r}}$)
}
\smallskip
\disleft 25pt:(3):
The operators {\tt +}$\,$, {\tt -}$\,$, {\tt *} are marked {\bf i}
if they connect two expressions
both marked {\bf i}:
\smallskip
{\obeylines\obeyspaces\let =\ \tt
M$↓{\bf{i}}$+$↓{\bf{i}}$3$↓{\bf{i}}$,N$↓{\bf{i}}$*$↓{\bf{i}}$(M+$↓{\bf{i}}$3)
}
\smallskip
\disleft 25pt::
where in the second example, we say that the expression {\tt M+3}
is marked with {\bf i}
because the plus sign that computes its value is so marked.
All other occurrences of {\tt +}$\,$, {\tt -}$\,$,
{\tt *}$\,$, {\bf /} are marked {\bf r}:
\smallskip
{\obeylines\obeyspaces\let =\ \tt
X$↓{\bf{r}}$+$↓{\bf{r}}$3$↓{\bf{i}}$,M$↓{\bf{i}}$/$↓{\bf{r}}$N$↓{\bf{i}}$,%
N$↓{\bf{i}}$+$↓{\bf{r}}$(M/$↓{\bf{r}}$N).
}
\smallskip
\disleft 25pt:(4):
The operators {\tt DIV} and {\tt MOD} are marked {\bf i},
and may be applied only to expressions marked~{\bf i}:
\smallskip
{\obeylines\obeyspaces\let =\ \tt
(M+$↓{\bf{i}}$3) DIV$↓{\bf{i}}$ 10$↓{\bf{i}}$,%
M$↓{\bf{i}}$ MOD$↓{\bf{i}}$ 60$↓{\bf{i}}$.
}
\smallskip
\disleft 25pt:(5):
The remaining standard functions of arithmetic ({\tt SQR}, {\tt ABS}) take the same
marking as the expressions to which they are applied:
\smallskip
{\obeylines\obeyspaces\let =\ \tt
SQR$↓{\bf{i}}$(M$↓{\bf{i}}$),SQR$↓{\bf{r}}$(M/$↓{\bf{r}}$N),%
ABS$↓{\bf{i}}$(M-$↓{\bf{i}}$N),ABS$↓{\bf{r}}$(X*$↓{\bf{r}}$Y).
}
\smallskip
\disleft 25pt:(6):
The standard functions of analysis ({\tt SIN}, {\tt COS}, {\tt ARCTAN},
{\tt EXP}, {\tt LN}, {\tt SQRT})
are marked~{\bf r},
whatever expressions they are applied to:
\smallskip
{\obeylines\obeyspaces\let =\ \tt
SIN$↓{\bf{r}}$(PI/$↓{\bf{r}}$6), EXP$↓{\bf{r}}$(SQR$↓{\bf{i}}$(M$↓{\bf{i}}$))
}
\smallskip
\disleft 25pt:(7):
All parts of a {\tt FOR} clause must be marked {\bf i}:
\smallskip
{\obeylines\obeyspaces\let =\ \tt
FOR M$↓{\bf{i}}$:=N$↓{\bf{i}}$ TO 2*N-$↓{\bf{i}}$1 DO ...
}
\smallskip
\disleft 25pt:(8):
All subscripts (which you don't know about yet) must be marked {\bf i}:
\smallskip
{\obeylines\obeyspaces\let =\ \tt
X[M$↓{\bf{i}}$,3$↓{\bf{i}}$]:=A[M DIV$↓{\bf{i}}$ 3]
}
\smallskip
\disleft 25pt:(9):
A real expression may not be assigned to an integer variable;
{\tt V${↓{\bf i}}$:=E${↓{\bf r}}$} is forbidden.
\vfill\eject
%\smallskip
\disleft 25pt:(10):
In a read command to a variable marked {\bf i},
\smallskip
{\obeylines\obeyspaces\let =\ \tt
READ(M$↓{\bf{i}}$),
}
\smallskip
\disleft 25pt::
the input number must be marked {\bf i}; if the variable is marked {\bf r}
\smallskip
{\obeylines\obeyspaces\let =\ \tt
READ(X$↓{\bf{r}}$),
}
\smallskip
\disleft 25pt::
the input number may be marked {\bf i} or {\bf r}.
\medskip
The difference between expressions marked {\bf i} and those marked {\bf r}
is in the computer's internal representation of their values. Most actual
computers use a non-decimal number base, but a typical decimal computer
would represent an {\bf i}-expression internally as a number of the
form $\pm$~{\tt DDDDDDDDDD} where each {\tt D} is a decimal digit;
if {\tt M} were~13, the value of
{\tt M-}$↓{\bf i}${\tt 27} would
then be represented as \hbox{{\tt -0000000014}$↓{\bf i}$}.
The same computer might internally
represent an {\bf r}-expression as a number of the
form $\pm$~{\tt D.DDDDDDD} $\times 10↑{\pm \hbox{\tt DD}}$;
if {\tt N} were~196, the value of
${\tt SQRT}↓{\bf r}{\tt (N)}$ would be represented by $+1.4000000\times 10↑{+01}$.
The two forms are called {\sl fixed point numbers\/} (more properly, fixed
point numerals, but nobody says that) and {\sl floating point numbers\/}
respectively.
Both representations have advantages. Usually, arithmetic on fixed point
numbers is a bit faster.
Floating point numbers have a greater range ($\pm 10↑{100}$ rather
than~$\pm 10↑{10}$, on the decimal machine), and are
allowed to have a fractional
part, like $1.2345678\times 10↑{04}=12345.678$. On the same machine,
if we compute $2↑{27}$, it is represented exactly as the fixed point
number 134217728, but only approximately as the floating point number
$1.3421773\times 10↑{08}$. In practice, programmers usually use fixed
point numbers to represent numbers resulting from counting, such as
census data, and floating point numbers to represent numbers
resulting from measurement, such as planetary radii.
When numbers are printed, they appear in a format that depends on whether
they are integer or real expressions. An integer expression appears as a
string of (typically) 12~characters. The string may begin with blanks, followed
by a minus sign if needed, followed by the value of the number.
Because the units digit is in the last position, it is easy to
print columns of numbers with correct vertical alignment. The total
number of characters printed is enough, at least, to accomodate
{\tt MAXINT}.
\smallskip
{\obeylines\obeyspaces\let =\ \tt
\hbox{\spa\spa\spa\spa\spa\spa\spa\spa\spa\spa\spa}0
\spa\spa\spa\spa\spa\spa\spa\spa\spa-10
\spa\spa{\spa}123456789
}
\smallskip
\noindent
A real expression appears as a string of
(typically) 16 characters in a floating-point format:
\smallskip
{\obeylines\obeyspaces\let =\ \tt
13.0 {\rm is printed} \spa1.300000000E+01, {\rm meaning $1.3\times 10↑1$}
1/3 {\rm is printed} \spa3.333333333E-01, {\rm meaning $3.333333333\times 10↑{-1}$}
}
\smallskip
If you don't care for these forms, you can override them. Use
{\tt WRITE(E:L)} instead of {\tt WRITE(E)},
where $L$ is an integer expression
(usually constant) saying how many characters of output you want.
\smallskip
{\obeylines\obeyspaces\let =\ \tt
WRITE(13) \spa\spa\spa\spa\spa\spa\spa\spa\spa{\spa}13
WRITE(13:3) {\spa}13
WRITE(1/3) {\spa}3.333333333E-01
WRITE(1/3:9) {\spa}3.33E-01
}
\smallskip
\noindent
To do this limits the size of integer values, and the precison of real values.
You can also print real values without an
exponent, by specifying how many digits after the decimal point should
be printed. Use {\tt WRITE}$(E:L:D)$, where $L$ is length as before, and
$D$ is an integer expression (usually constant) saying how many digits
you want after the decimal point.
\smallskip
{\obeylines\obeyspaces\let =\ \tt
WRITE(1/3:7:2) \spa\spa\spa0.33
WRITE(1000/3:7:2) \spa333.33
}
\smallskip
\noindent
This form is also called fixed point; the numbers above have decimal points
in the same position.
If you print a number too large for the length you have allotted, the system
overrides your specified length:
\smallskip
{\obeylines\obeyspaces\let =\ \tt
WRITE(123:2) 123
WRITE(1000/3:5:2) \spa333.33
}
\smallskip\noindent
This can be
useful when you want to print numbers within a sentence; the
command {\tt WRITE('There are ', I:1 ' airplanes approaching.'}) can result in
\smallskip
{\obeylines\obeyspaces\let =\ \tt
There are 2 airplanes approaching.
}
\smallskip\noindent
or
\smallskip
{\obeylines\obeyspaces\let =\ \tt
There are 2000000 airplanes approaching.
}
\smallskip
\noindent
A minor nuisance: Pascal, in printing real values in floating point form,
{\sl always\/} starts
a positive number with a space. There is no
way to get rid of it, except by providing your own output subprogram.
\bigskip\bigskip
\noindent{\bf Case Study: How to Print Money.}
I am a programmer for a bank, writing programs to maintain balances, adding
deposits and subtracting withdrawals. Once a month the program must print
an itemized statement.
I could use a real variable for each customer's balance, but then interest
calculations would result in balances like \$123.45678, with amounts in
fractional cents. I~could print those amounts in a form like \$123.46, but
the fractions would still be there and could accumulate to be greater
than~\$0.01, so that money would seem to appear from nowhere. Instead I~decide
to let the variables for money amounts be counted in cents
({\tt VAR CHECK, DEPOSIT, BALANCE, WITHD:INTEGER}). When reading a check,
then, I~must do this:
\smallskip
{\obeylines\obeyspaces\let =\ \tt
VAR DOLLARCHK:REAL;
$\vdots$
READ(DOLLARCHK);
CHECK:=ROUND(DOLLARCHK*100)
}
(Drill: Why would it be a mistake to use
{\tt CHECK:=TRUNC(DOLLARCHK*100)}$\;$?
[Because this could convert a tiny error in the value of {\tt DOLLARCHK*100}
into a one-cent deficiency in {\tt CHECK}.]
\vfill\eject
%\smallskip
Interest computations are straightforward; for 5\%\ interest, I~write
\smallskip
{\obeylines\obeyspaces\let =\ \tt
INTEREST:=TRUNC(BALANCE*0.05);
BALANCE:=BALANCE+INTEREST.
}
\smallskip
\noindent
When I print lines of dollar amounts in tabular form:
\smallskip
{\obeylines\obeyspaces\let =\ \tt
INITIAL BALANCE 100.03
DEPOSIT: 5.00 105.03
WITHDRAWAL: 94.02 9.01
}
\smallskip
\noindent
I must allow for the longest numbers:
\smallskip
{\obeylines\obeyspaces\let =\ \tt
WRITE('INITIAL{\spa}BALANCE\spa\spa\spa',BALANCE/100:7:2);
$\vdots$
WRITE('DEPOSIT:\spa\spa\spa',DEPOSIT/100:7:2,BALANCE/100:7:2;
$\vdots$
WRITE('WITHDRAWAL:',WITHD/100:7:2,BALANCE/100:7:2;
$\vdots$
}
\smallskip\noindent
to ensure that decimal points line up vertically. On the other hand,
when dollar amounts appear in English text:
\smallskip
{\obeylines\obeyspaces\let =\ \tt
YOUR ACCOUNT IS OVERDRAWN BY 123.45 DOLLARS
YOUR ACCOUNT IS OVERDRAWN BY 1.23 DOLLARS
}
\smallskip\noindent
I must allow for the shortest numbers to avoid extra spaces, relying on the
output subprograms to provide more room for larger numbers.
\smallskip
{\obeylines\obeyspaces\let =\ \tt
WRITE('YOUR ACCOUNT IS OVERDRAWN BY',-BALANCE/100:4:2,'DOLLARS')
}
%\vfill\eject
\bigskip\bigskip
\line{{\bf Case Study: A Compact Table.} (Output format.)\hfil}
I want to print a table of probabilities on a narrow page. By definition,
probabilities lie between zero and one, so they are kept in {\bf r}-variables.
I~could use:
\smallskip
{\obeylines\obeyspaces\let =\ \tt
WRITELN(P1:6:3,P2:6:3,P3:6:3)
}
\smallskip\noindent
to get
\smallskip
{\obeylines\obeyspaces\let =\ \tt
0.999 0.500 0.250
0.125 0.062 0.031
}
\smallskip\noindent
but if I am sure that no probability is as large as 0.9995, I~could print
each as an {\bf i}-value, scaled up by a factor of 1000, by
\smallskip
{\obeylines\obeyspaces\let =\ \tt
WRITE(ROUND(P1*1000):4)\hbox{, to get}
999 500 250
125 62 31
}
\vfill\eject
To avoid suppression of leading zeroes, as in printing
\smallskip
{\obeylines\obeyspaces\let =\ \tt
001
002
004
008
016
032
$\vdots$
512
}
\smallskip\noindent
the simplest solution is to print the number one digit at a time:
\smallskip
{\obeylines\obeyspaces\let =\ \tt
$\vdots$ $\vdots$ $\vdots$
WRITE(P DIV 100:1, P DIV 10 MOD 10:1, P MOD 10:1)
}
\bigskip
\parindent0pt
\copyright 1984 Robert W. Floyd; First draft July 20, 1984.
\bye